Opensky

OpenSky provides api to get data for flights in progress. It is rate limited

Code
import requests
import pandas as pd
import geopandas
Code
def fetch_opensky_data():
    url = "https://opensky-network.org/api/states/all"
    response = requests.get(url)
    data = response.json()

    columns = [
        "icao24", "callsign", "origin_country", "time_position", "last_contact",
        "longitude", "latitude", "baro_altitude", "on_ground", "velocity",
        "heading", "vertical_rate", "sensors", "geo_altitude", "squawk",
        "spi", "position_source"
    ]

    df_raw = pd.DataFrame(data['states'], columns=columns)
    return (
        df_raw
        .assign(
            time_position=pd.to_datetime(df_raw["time_position"], unit="s"),
            last_contact=pd.to_datetime(df_raw["last_contact"], unit="s"),
        )
    )

df_flights = fetch_opensky_data()


df_flihts_non_nan = df_flights.dropna(subset=["longitude", "latitude"])
gdf = geopandas.GeoDataFrame(
    df_flihts_non_nan,
    geometry=geopandas.points_from_xy(df_flihts_non_nan.longitude, df_flihts_non_nan.latitude),
    crs="EPSG:4326",
)

gdf.explore(fullscreen=True, tooltip=False, popup=True)
Make this Notebook Trusted to load map: File -> Trust Notebook

Flights in world at notebook time

Number of flights by origin_country

Code
(
    df_flights
    .groupby("origin_country")
    .agg(num_flights=("icao24", "count"))
    .sort_values("num_flights", ascending=False)
    .head(20)
)
num_flights
origin_country
United States 1368
Australia 327
China 256
Germany 250
Ireland 221
India 215
Turkey 212
United Kingdom 183
Japan 183
France 166
Malta 144
Spain 138
Austria 132
Canada 128
Kingdom of the Netherlands 121
United Arab Emirates 109
Switzerland 86
Thailand 75
Republic of Korea 74
Poland 72

Top 20 countries with most flights

All flights

For reference

Code
df_flights
icao24 callsign origin_country time_position last_contact longitude latitude baro_altitude on_ground velocity heading vertical_rate sensors geo_altitude squawk spi position_source
0 39de4f TVF29UL France 2025-05-22 05:17:51 2025-05-22 05:17:51 4.1351 40.9820 11582.40 False 231.26 27.71 0.00 None 11803.38 1000 False 0
1 39de4b TVF32ER France 2025-05-22 05:17:50 2025-05-22 05:17:51 1.1356 45.7228 10355.58 False 212.04 358.33 -0.33 None 10408.92 1000 False 0
2 39de4c TVF3423 France 2025-05-22 05:17:50 2025-05-22 05:17:50 18.9498 44.2522 11574.78 False 215.18 285.53 0.33 None 11727.18 5316 False 0
3 407a38 NPT902 United Kingdom 2025-05-22 05:17:50 2025-05-22 05:17:50 -1.7468 50.5203 4876.80 False 156.92 203.37 0.33 None 4960.62 5140 False 0
4 801644 FLG708 India 2025-05-22 05:17:51 2025-05-22 05:17:51 78.4740 29.9195 3048.00 False 70.94 315.88 0.00 None 3131.82 None False 0
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
5705 47bfb3 NSZ3LZ Norway 2025-05-22 05:17:50 2025-05-22 05:17:50 0.8705 38.7302 7178.04 False 217.71 68.22 8.13 None 7437.12 5343 False 0
5706 4caa59 RYR87FC Ireland 2025-05-22 05:17:50 2025-05-22 05:17:50 7.6107 44.2233 11277.60 False 205.93 239.53 0.33 None 11399.52 2250 False 0
5707 398570 AFR76BR France 2025-05-22 05:17:50 2025-05-22 05:17:50 4.8580 47.6055 8633.46 False 235.08 321.58 -4.88 None 8602.98 1000 False 0
5708 a0c7b3 ABX3102 United States 2025-05-22 05:17:50 2025-05-22 05:17:50 -80.1244 41.4330 11285.22 False 252.33 72.19 0.00 None 11323.32 4043 False 0
5709 458666 VKG1512 Denmark 2025-05-22 05:17:49 2025-05-22 05:17:50 11.0709 60.3134 1463.04 False 136.84 301.00 11.38 None 1409.70 6005 False 0

5710 rows × 17 columns